﻿[assembly:
        System.Web.UI.WebResource("BM.Tools.WebControls.MForm.Controls.Additions.DynamicPopulateAddition.js",
                "application/x-javascript")]
[assembly:
        System.Web.UI.WebResource("BM.Tools.WebControls.MForm.Controls.Additions.DynamicPopulateAddition.debug.js",
                "application/x-javascript")]

namespace BM.Tools.WebControls.MForm.Controls.Additions
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Web.UI;

    using AjaxControlToolkit;

    using BM.Tools.WebControls.MForm.Controls.Helper;
    using BM.Tools.WebControls.MForm.Controls.Items;
    using BM.Tools.WebControls.MForm.ScriptReferences;

    /// <summary>
    /// The control that runs the dynamic populate functionality on item's value change
    /// </summary>
    [ClientScriptResource("BM.Tools.WebControls.MForm", "BM.Tools.WebControls.MForm.Controls.ExtenderDuplicator.js")]
    [ClientScriptResource("BM.Tools.WebControls.MForm",
            "BM.Tools.WebControls.MForm.Controls.Additions.DynamicPopulateAddition.js")]
    public class DynamicPopulateAddition : Addition, IScriptControl
    {
        private JQueryComponentDescriptor descriptor;

        private string jQuerySelector = "." + LeafItem.InputCssClass;

        /// <summary>
        /// Gets Descriptor.
        /// </summary>
        public JQueryComponentDescriptor Descriptor
        {
            get
            {
                if (descriptor == null)
                {
                    descriptor = CreateDescriptor();
                }

                return descriptor;
            }
        }

        /// <summary>
        /// Gets or sets Extender.
        /// </summary>        
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public DynamicPopulateExtender Extender
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets JQuerySelector.
        /// </summary>        
        [DefaultValue("." + LeafItem.InputCssClass)]
        public string JQuerySelector
        {
            get
            {
                return jQuerySelector;
            }

            set
            {
                jQuerySelector = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the dynamic populate should be invoked on client side on load complete, by default this value is false.
        /// </summary>
        [DefaultValue(false)]
        [AttributeProperty(Name = "invokeOnLoadComplete")]
        public bool InvokeOnLoadComplete
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets xpath like path to the affected item.
        /// </summary>
        public string Path
        {
            get;
            set;
        }

        /// <summary>
        /// Gets Selector.
        /// </summary>
        public string Selector
        {
            get
            {
                return "BM.DynamicPopulateAddition.find('" + Owner.ClientID + "', " + (Owner.ClientID.Length - CommonLength) + ", '" + PopulateTriggerItem.ClientID.Substring(CommonLength) + "', '" + JQuerySelector + "')";                
            }
        }

        /// <summary>
        /// Gets the index of the dnamic populate addition (to differentiate from other dynamic populate additions).
        /// </summary>
        [AttributeProperty(Name = "index")]
        public int Index
        {
            get
            {
                return Owner.Additions.OfType<DynamicPopulateAddition>().ToList().IndexOf(this);
            }
        }

        /// <summary>
        /// Gets PopulateTriggerItem.
        /// </summary>
        protected LeafItem PopulateTriggerItem
        {
            get
            {
                return Owner.SelectSingle(Path) as LeafItem;
            }
        }

        private int CommonLength
        {
            get
            {
                var commonLength = Math.Min(Owner.ClientID.Length, PopulateTriggerItem.ClientID.Length);
                for (var i = 0; i < commonLength; i++)
                {
                    if (Owner.ClientID[i] != PopulateTriggerItem.ClientID[i])
                    {
                        return i;
                    }
                }

                return commonLength;
            }
        }

        /// <summary>
        /// returns script descriptors
        /// </summary>
        /// <returns>
        /// the enumeration of script descriptors
        /// </returns>
        public IEnumerable<ScriptDescriptor> GetScriptDescriptors()
        {
            yield return Descriptor;
        }

        /// <summary>
        /// returns script references
        /// </summary>
        /// <returns>
        /// the enumeration of script references
        /// </returns>
        public IEnumerable<ScriptReference> GetScriptReferences()
        {            
            return ScriptObjectBuilder.GetScriptReferences(Extender.GetType());
        }

        /// <summary>
        /// registers script control and script descriptors
        /// </summary>
        /// <param name="e">
        /// The event args.
        /// </param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            ScriptManager sm = ScriptManager.GetCurrent(Page);
            if (sm == null)
            {
                return;
            }

            sm.RegisterScriptControl(this);
            sm.RegisterScriptDescriptors(this);
        }

        /// <summary>
        /// creates a descriptor for dynamic populate functionality
        /// </summary>
        /// <returns>
        /// the created descriptor
        /// </returns>
        private JQueryComponentDescriptor CreateDescriptor()
        {
            var componentDescriptor =
                    new JQueryComponentDescriptor("AjaxControlToolkit.DynamicPopulateBehavior", Selector);
            componentDescriptor.ID = Owner.ClientID + "_DP" + Index;            
            ScriptObjectBuilder.DescribeComponent(Extender, componentDescriptor, this, Extender);
            return componentDescriptor;
        }
    }
}